package com.atguigu.gmall.product.controller;

import io.netty.util.concurrent.DefaultThreadFactory;

import java.util.concurrent.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * @author mgx
 * @version 1.0
 * @description: 测试使用CompletableFuture
 * @date 2022/11/10 13:32
 */
public class CompletableFutureDemo {

    public static void main(String[] args) {
        // 测试线程的串行化和并行化
        // 测试案例：任务B和C依赖任务A, 且都是异步执行，B睡眠2秒测试此时是不是并行化执行
        // 创建线程池
        ThreadPoolExecutor threadPoolExecutor =
                new ThreadPoolExecutor(50, 500, 30,
                        TimeUnit.SECONDS, new ArrayBlockingQueue<>(10000));
        CompletableFuture<Object> futureA = CompletableFuture.supplyAsync(new Supplier<Object>() {
            @Override
            public Object get() {
                return "404";
            }
        }, threadPoolExecutor);

        // 创建任务B
        futureA.thenAcceptAsync(new Consumer<Object>() {
            @Override
            public void accept(Object o) {
                try {
                    Thread.sleep(2000);
                    System.out.println("任务B");
                    System.out.println(Thread.currentThread().getName());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, threadPoolExecutor);

        // 创建任务C
        futureA.thenAcceptAsync(new Consumer<Object>() {
            @Override
            public void accept(Object o) {
                System.out.println("任务C");
                System.out.println(Thread.currentThread().getName());
            }
        }, threadPoolExecutor);
    }

    public static void main1(String[] args) throws ExecutionException, InterruptedException {
        // 创建没有返回值的异步执行对象
        // CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
        //     System.out.println("没有返回值的异步对象");
        // });

        // System.out.println(future.get());

        // 创建有返回值的异步执行对象
        CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(new Supplier<Integer>() {
            @Override
            public Integer get() {
                int i = 1 / 0;
                return 404;
            }
        }).whenComplete(new BiConsumer<Integer, Throwable>() {
            /**
             * 和异步执行对象使用的是同一个线程
             * 处理异步回调任务
             * @param integer: 异步任务的返回值
             * @param throwable: 异步任务的异常对象
             */
            @Override
            public void accept(Integer integer, Throwable throwable) {
                System.out.println("whenComplete:" + integer);
                System.out.println("whenComplete:" + throwable);
            }
        }).exceptionally(new Function<Throwable, Integer>() {
            /**
             * 处理异步任务的异常
             * @param throwable: 抛出的异常对象
             * @return
             */
            @Override
            public Integer apply(Throwable throwable) {
                System.out.println("exceptionally:" + throwable);
                return null;
            }
        }).whenCompleteAsync(new BiConsumer<Integer, Throwable>() {
            /**
             * 和异步任务的线程可能不是同一个，是把执行回调的任务重新交给线程池来分配执行
             * @param integer: 异步任务的返回值
             * @param throwable: 异步任务的异常对象
             */
            @Override
            public void accept(Integer integer, Throwable throwable) {
                System.out.println("whenCompleteAsync:" + integer);
                System.out.println("whenCompleteAsync:" + throwable);
            }
        });

    }
}
